package cn.wolfcode.luowowo.redis.redisService.impl;

import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.StrategyCatalog;
import cn.wolfcode.luowowo.redis.key.RedisKeys;
import cn.wolfcode.luowowo.redis.redisService.IStrategyFavorRedisService;
import cn.wolfcode.luowowo.redis.redisService.IStrategyStatisVoService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.util.DBHelper;
import cn.wolfcode.luowowo.util.DateUtil;
import cn.wolfcode.luowowo.vo.FavorStrategyVO;
import cn.wolfcode.luowowo.vo.StrategyStatisVO;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.TimeUnit;


@Service
public class StrategyStatisVoServiceImpl implements IStrategyStatisVoService {

    @Autowired
    private StringRedisTemplate template;
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private IStrategyFavorRedisService strategyFavorRedisService;

    @Override
    public void replynumIncrease(String strategyId, int i) {
        //1.获取缓存中的vo对象
        //在获取方法中已判断了存在不存在的两种情况处理操作
        StrategyStatisVO vo = this.getStrategyStatisVo(strategyId);

        //2.把vo对象中的viewnum 加1
        vo.setReplynum(vo.getReplynum() + 1);

        //3.更新vo对象到缓存中
        this.setStrategyStatisVo(vo);
    }

    @Override
    public void viewnumIncrease(String strategyId, int i) {
        //1.获取缓存中的vo对象
        //在获取方法中已判断了存在不存在的两种情况处理操作
        StrategyStatisVO vo = this.getStrategyStatisVo(strategyId);

        //2.把vo对象中的viewnum 加1
        vo.setViewnum(vo.getViewnum() + 1);

        //3.更新vo对象到缓存中
        this.setStrategyStatisVo(vo);
    }

    //获取vo对象
    @Override
    public StrategyStatisVO getStrategyStatisVo(String strategyId) {
        //1.根据攻略id 拼接缓存中攻略统计数据的key
        String key = RedisKeys.STRATEGY_STATIS_VO.join(strategyId);

        //2.判断key是否存在 获取或初始化vo
        StrategyStatisVO vo = null;
        if (template.hasKey(key)) {
            //若存在,直接根据key获取并转换成对象
            String value = template.opsForValue().get(key);
            vo = JSON.parseObject(value, StrategyStatisVO.class);
        } else {
            //若key不纯在 初始化一个vo对象 并存入缓存中
            //先从数据库中查询出当前攻略的统计数据对象 并拷贝数据到vo对象
            Strategy strategy = strategyService.get(strategyId);
            vo = new StrategyStatisVO();
            BeanUtils.copyProperties(strategy, vo);
            vo.setStrategyId(strategyId);//字段不同所以单独赋值
            //vo对象初始化完 存入缓存中
            template.opsForValue().set(key, JSON.toJSONString(vo));
        }
        return vo;
    }

    //存入vo对象
    @Override
    public void setStrategyStatisVo(StrategyStatisVO vo) {
        String key = RedisKeys.STRATEGY_STATIS_VO.join(vo.getStrategyId());
        template.opsForValue().set(key, JSON.toJSONString(vo));
    }

    //收藏或取消收藏操作
    @Override
    public boolean favor(String strategyId, String userInfoId) {

        //1.根据用户id获取在缓存中的FavorStrategyVO
        FavorStrategyVO favorStrategyVO = strategyFavorRedisService.getFavorRedis(userInfoId);
        //在对象中过去收藏的攻略id集合
        List<String> list = Collections.emptyList();
        if (favorStrategyVO != null) {
            list = favorStrategyVO.getFavorStrategyIds();
        }
        //2.判断当前攻略id 在不在 已收藏的攻略id集合中
        //先获取缓存中的vo对象
        StrategyStatisVO vo = this.getStrategyStatisVo(strategyId);
        boolean ret = true;
        if (list.contains(strategyId)) {
            //3.如果在 即当前操作是取消收藏 并使收藏数 -1
            //在已收藏的攻略id集合中 移除当前攻略id
            list.remove(strategyId);
            //使收藏数 -1
            vo.setFavornum(vo.getFavornum() - 1);
            ret = false;//取消收藏返回结果是false
        } else {
            //4.如果不在 即当前操作是收藏 并使收藏数 +1
            //把当前攻略id 增加到已收藏的攻略id集合
            list.add(strategyId);
            //使收藏数 +1
            vo.setFavornum(vo.getFavornum() + 1);
            ret = true;//收藏返回结果是true
        }
        //3.更新list , vo到缓存中
        strategyFavorRedisService.setFavorRedis(userInfoId, list);
        this.setStrategyStatisVo(vo);
        return ret;
    }

    @Override
    public boolean thumbup(String strategyId, String userInfoId) {
        // 1.根据用户id和攻略id拼接key
        String key = RedisKeys.STRATEGY_THUMBUP.join(userInfoId, strategyId);

        // 2.如果不存在
        if (!template.hasKey(key)) {
            Date date = new Date();//当前时间
            Date endDate = DateUtil.getEndDate(date);//当天的最后一秒对象
            // 有效时间等于 = 当天的最后一秒 - 当前秒
            long time = DateUtil.getDateBetween(date, endDate);

            // 创建缓存标记 设置有效时间 (当天的最后一秒减去当前秒)
            template.opsForValue().set(key, "1", time, TimeUnit.SECONDS);
            // 使点赞数加一
            StrategyStatisVO vo = this.getStrategyStatisVo(strategyId);
            vo.setThumbsupnum(vo.getThumbsupnum() + 1);
            // 更新Vo对象
            this.setStrategyStatisVo(vo);
            return true;
        } else {
            //3. 如果标记已存在 不做其他操作
            return false;
        }
    }

    @Override
    public boolean isVoExsits(String strategyId) {
        StrategyStatisVO vo = this.getStrategyStatisVo(strategyId);
        if (vo == null) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public List<StrategyStatisVO> listStrategyVoByPattern(String pattern) {

        //1.使用keys strategy_statis_vo:* 方法获取所有key
        Set<String> keys = template.keys(pattern);

        //2.遍历所有key获取所有vo对象
        ArrayList<StrategyStatisVO> vos = new ArrayList<>();
        if (keys.size() > 0 && keys != null) {
            for (String key : keys) {
                String voStr = template.opsForValue().get(key);
                StrategyStatisVO strategyStatisVO = JSON.parseObject(voStr, StrategyStatisVO.class);
                vos.add(strategyStatisVO);
            }
        }
        return vos;
    }

    //把攻略vo中的数据 存入mongodb中对应的攻略中
    @Override
    public void updateStrategyVo(StrategyStatisVO vo) {

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(vo.getStrategyId()));
        //从vo拷贝数据到strategy
        Strategy strategy = new Strategy();
        BeanUtils.copyProperties(vo, strategy);
        DBHelper.update(mongoTemplate, query, strategy, "viewnum",
                "replynum", "favornum", "sharenum", "thumbsupnum");
    }

    @Override
    public ArrayList<FavorStrategyVO> listStrategFavorByPattern(String pattern) {
        //1.使用keys strategy_statis_vo:* 方法获取所有key
        Set<String> keys = template.keys(pattern);

        ArrayList<FavorStrategyVO> favorStrategyVoList = new ArrayList<>();
        //2.遍历所有key获取
        if (keys.size() > 0 && keys != null) {
            for (String key : keys) {
                String voStr = template.opsForValue().get(key);
                FavorStrategyVO favorStrategyVO = JSON.parseObject(voStr, FavorStrategyVO.class);
                favorStrategyVoList.add(favorStrategyVO);
            }
        }
        return favorStrategyVoList;
    }
}
